ส่วนขยาย Chrome: เส้นทางการทดสอบการระงับการทำงานของ Service Worker

นี่เกี่ยวกับอะไร

การเปลี่ยนจากไฟล์ Manifest V2 ไปใช้ไฟล์ Manifest V3 มาพร้อมกับการเปลี่ยนแปลงพื้นฐาน ในไฟล์ Manifest V2 ส่วนขยายทำงานอยู่ในหน้าพื้นหลัง หน้าเว็บพื้นหลังจัดการการสื่อสารระหว่างส่วนขยายและหน้าเว็บ ไฟล์ Manifest V3 จะใช้ Service Worker แทน

ในโพสต์นี้ เราได้เจาะลึกปัญหาของการทดสอบโปรแกรมทำงานของบริการส่วนขยาย ที่สำคัญคือเราจะมาดูวิธีตรวจสอบว่าผลิตภัณฑ์ของเราทำงานอย่างถูกต้องหรือไม่ ในกรณีที่มีการระงับโปรแกรมทำงานของบริการ

เราคือใคร

eyeo คือบริษัทที่มุ่งมั่นส่งเสริมการแลกเปลี่ยนคุณค่าทางออนไลน์ที่สมดุลและยั่งยืนสำหรับผู้ใช้ เบราว์เซอร์ ผู้ลงโฆษณา และผู้เผยแพร่โฆษณา เรามีผู้ใช้ที่กรองโฆษณาทั่วโลกมากกว่า 300 ล้านคนซึ่งอนุญาตให้แสดงโฆษณาที่ยอมรับได้ ซึ่งเป็นมาตรฐานโฆษณาที่ได้รับมาอย่างอิสระและพิจารณาว่าโฆษณานั้นยอมรับหรือไม่รบกวนโฆษณา

ทีมเครื่องมือส่วนขยายของเรามีเทคโนโลยีการกรองโฆษณาที่ช่วยขับเคลื่อนส่วนขยายเบราว์เซอร์บล็อกโฆษณาที่ได้รับความนิยมสูงสุดในตลาด เช่น AdBlock และ Adblock Plus ที่มีผู้ใช้มากกว่า 110 ล้านคนทั่วโลก นอกจากนี้ เรายังมีเทคโนโลยีนี้เป็นไลบรารีโอเพนซอร์ส ซึ่งทำให้ส่วนขยายอื่นๆ ของเบราว์เซอร์กรองโฆษณาใช้งานได้

โปรแกรมทำงานของบริการคืออะไร

ผู้ปฏิบัติงานของบริการส่วนขยายคือเครื่องจัดการเหตุการณ์ส่วนกลางของส่วนขยายเบราว์เซอร์ โดยจะทำงานอย่างอิสระอยู่เบื้องหลัง กว้างๆ ก็ได้ค่ะ เราทำสิ่งต่างๆ ส่วนใหญ่ที่จำเป็นได้ในหน้าเว็บพื้นหลังของ Service Worker ใหม่ แต่มีการเปลี่ยนแปลงเล็กน้อยเมื่อเทียบกับหน้าพื้นหลัง ดังนี้

  • โปรแกรมทำงานของบริการจะหยุดการทำงานเมื่อไม่ได้ใช้งาน เราจึงต้องคงสถานะแอปพลิเคชันไว้แทนที่จะพึ่งพาตัวแปรร่วม ซึ่งหมายความว่า เราต้องเตรียมการเรียกใช้จุดแรกเข้าในระบบของเราก่อนที่จะเริ่มต้นระบบ
  • ต้องแนบ Listener เหตุการณ์ก่อนที่จะรอให้โค้ดเรียกกลับแบบไม่พร้อมกัน โดย Service Worker ที่ถูกระงับจะยังคงรับกิจกรรมที่ได้สมัครใช้บริการไว้ หาก Listener เหตุการณ์ไม่ได้ลงทะเบียนในเทิร์นแรกของการวนซ้ำเหตุการณ์ ก็จะไม่ได้รับเหตุการณ์หากเหตุการณ์นั้นปลุก Service Worker ให้ตื่นขึ้น
  • การสิ้นสุดการไม่ใช้งานอาจรบกวนตัวจับเวลาก่อนที่จะทำงานเสร็จ

เมื่อใดที่ Service Worker จะถูกระงับ

สำหรับ Chrome 119 สิ่งที่เราพบคือโปรแกรมทำงานของบริการถูกระงับ

  • หลังจากไม่ได้รับเหตุการณ์หรือ API ของส่วนขยายการโทรเป็นเวลา 30 วินาที
  • ไม่เลยหากเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์เปิดอยู่หรือคุณกำลังใช้ไลบรารีการทดสอบที่ใช้ ChromeDriver (ดูคำขอฟีเจอร์)
  • หากคลิก Stop ใน chrome://serviceworker-internals

ดูข้อมูลล่าสุดได้ที่วงจรการทำงานของ Service Workers

เหตุใดการทดสอบนี้จึงเป็นปัญหา

หากจะให้แนวทางอย่างเป็นทางการเกี่ยวกับ "วิธีทดสอบ Service Worker อย่างมีประสิทธิภาพ" หรือตัวอย่างการทดสอบที่ใช้งานได้ก็น่าจะมีประโยชน์มากเช่นกัน ในระหว่างที่เราดำเนินการทดสอบโปรแกรมทำงาน เราต้องเผชิญกับความท้าทายบางประการดังนี้

  • เราได้ระบุในส่วนขยายที่ทดสอบของเรา เมื่อ Service Worker หยุดทำงาน เราจะสูญเสียสถานะและกิจกรรมที่ลงทะเบียนไว้ เราจะรักษาข้อมูลไว้ในขั้นตอนการทดสอบได้อย่างไร
  • หากมีการระงับโปรแกรมทำงานของบริการได้ทุกเมื่อ เราต้องทดสอบว่าฟีเจอร์ทั้งหมดใช้งานได้หากถูกขัดจังหวะ
  • ถึงแม้ว่าเราจะแนะนำกลไกในการทดสอบที่จะระงับ Service Worker แบบสุ่ม แต่ก็ไม่มี API ในเบราว์เซอร์ที่จะระงับได้โดยง่าย เราได้ขอให้ทีม W3C เพิ่มฟีเจอร์นี้ แต่นั่นเป็นการสนทนาที่ดำเนินอยู่อย่างต่อเนื่อง

การระงับผู้ปฏิบัติงานบริการทดสอบ

เราได้ลองหลายวิธีเพื่อทำให้เกิดการระงับ Service Worker ในระหว่างการทดสอบ ดังนี้

วิธีการ ปัญหาเกี่ยวกับแนวทาง
รอตามระยะเวลาที่ต้องการ (เช่น 30 วินาที) ซึ่งทำให้การทดสอบช้าลงและไม่น่าเชื่อถือ โดยเฉพาะเมื่อทำการทดสอบหลายรายการ ไม่ทำงานเมื่อใช้ WebDriver เนื่องจาก WebDriver ใช้ API เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome และโปรแกรมทำงานของบริการจะไม่ถูกระงับเมื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ แม้ว่าจะข้ามผ่านได้ เราก็ยังคงต้องตรวจสอบว่า Service Worker ถูกระงับหรือไม่ และไม่มีวิธีดำเนินการดังกล่าว
เรียกใช้การวนซ้ำแบบไม่สิ้นสุดในโปรแกรมทำงานของบริการ ตามข้อกำหนดนี้อาจนำไปสู่การสิ้นสุดได้โดยขึ้นอยู่กับวิธีที่เบราว์เซอร์ใช้ฟังก์ชันการทำงานนี้ Chrome จะไม่ยุติโปรแกรมทำงานของบริการในกรณีนี้ ดังนั้นเราจึงไม่สามารถทดสอบสถานการณ์เมื่อโปรแกรมทำงานของบริการถูกระงับ
มีข้อความลงใน Service Worker เพื่อตรวจสอบว่าถูกระงับหรือไม่ การส่งข้อความปลุกระบบทำงานให้กับ Service Worker ซึ่งอาจใช้ในการตรวจสอบว่า Service Worker อยู่ในโหมดสลีปหรือไม่ แต่จะแบ่งผลลัพธ์ของการทดสอบที่ต้องดำเนินการทันทีหลังระงับ Service Worker ได้
ยุติกระบวนการทำงานของบริการโดยใช้ chrome.Processes.terminate() โปรแกรมทำงานของบริการสำหรับส่วนขยายนั้นแชร์กระบวนการกับส่วนอื่นๆ ของส่วนขยาย ดังนั้นการปิดกระบวนการนี้โดยใช้ chrome.Process.terminate() หรือ GUI ของตัวจัดการกระบวนการของ Chrome จะไม่เพียงแค่ปิดเฉพาะ Service Worker เท่านั้น แต่ยังรวมถึงหน้าต่างๆ ของส่วนขยายด้วย

เราได้ทำการทดสอบที่ตรวจสอบการตอบสนองของโค้ดต่อ Service Worker ที่ถูกระงับโดยให้ Selenium WebDriver เปิด chrome://serviceworker-internals/ แล้วคลิกปุ่ม "หยุด" ของ Service Worker

นี่เป็นตัวเลือกที่ดีที่สุดสำหรับตอนนี้ แต่ก็ยังไม่ดีที่สุดเนื่องจากการทดสอบ Mocha (ซึ่งทำงานบนหน้าส่วนขยาย) ไม่สามารถดำเนินการด้วยตนเองได้ พวกเขาจึงต้องสื่อสารกลับไปยังโปรแกรมโหนด WebDriver ซึ่งหมายความว่า การทดสอบเหล่านี้จะใช้เพียงส่วนขยายไม่ได้ และจะต้องทริกเกอร์โดยใช้ Selenium WebDriver

นี่คือแผนภาพวิธีที่เราสื่อสารกับ API ของเบราว์เซอร์ผ่านขั้นตอนต่างๆ และผลของกลไก "ระงับ Service Worker"

แผนภาพแสดงขั้นตอนการทดสอบ
การทดสอบขั้นตอนการดำเนินการที่มีการระงับ Service Worker

ในขั้นตอนใหม่ที่ระงับ Service Worker (สีฟ้า) เราได้เพิ่ม Selenium WebDriver ให้ "คลิก" ระงับผ่าน UI ซึ่งจะทริกเกอร์การดำเนินการใน API ของเบราว์เซอร์

โปรดทราบว่ามีข้อบกพร่องของ Chrome ที่การดำเนินการนี้โดยใช้ Selenium WebDriver ทำให้โปรแกรมทำงานของบริการไม่สามารถเริ่มต้นอีกครั้งได้ ปัญหานี้ได้รับการแก้ไขแล้วใน Chrome 116 และโชคดีที่ยังมีวิธีแก้ปัญหาเฉพาะหน้า นั่นคือการตั้งค่า Chrome ให้เปิดเครื่องมือสำหรับนักพัฒนาเว็บโดยอัตโนมัติในทุกแท็บ ทำให้โปรแกรมทำงานของบริการเริ่มทำงานได้อย่างถูกต้อง

เราใช้แนวทางนี้เมื่อทดสอบแม้ว่าจะไม่เหมาะสมเนื่องจากการคลิกปุ่มอาจไม่ใช่ API ที่เสถียรและการเปิดเครื่องมือสำหรับนักพัฒนาเว็บ (สำหรับเบราว์เซอร์รุ่นเก่า) จะเสียค่าใช้จ่ายด้านประสิทธิภาพ

เราจะครอบคลุมฟังก์ชันทั้งหมดได้อย่างไร การทดสอบ Fuzz

เมื่อเรามีกลไกสำหรับการทดสอบการระงับแล้ว เราต้องตัดสินใจว่าจะนำมาใช้กับชุดทดสอบอัตโนมัติอย่างไร เราทำการทดสอบมาตรฐานในสภาพแวดล้อมที่ก่อนการโต้ตอบกับหน้าเว็บเบื้องหลังแต่ละครั้ง Service Worker ถูกระงับโดย WebDriver คลิก Stop ในหน้า chrome://serviceworker-internals/

ตัวอย่างการเรียกใช้การทดสอบ Fuzz
รูปภาพแสดงการทดสอบในปัจจุบัน

เราทำการทดสอบส่วนใหญ่ ไม่ใช่ทั้งหมด เนื่องจากกลไกการระงับทำงานไม่เสถียรนัก และบางครั้งอาจทำให้ผู้ใช้ไม่เสถียร นอกจากนี้ การเรียกใช้ชุดทดสอบทั้งหมดในโหมด Fuzz อาจใช้เวลานาน เราจึงเลือกเส้นทางที่สำคัญที่สุดสำหรับการทดสอบในโหมด Fuzz แทนที่จะครอบคลุมกรณี "ที่คล้ายกัน" ทั้งหมด โปรดทราบว่าการเรียกใช้การทดสอบฟังก์ชันในโหมด "fuzz" ทำให้เราต้องเพิ่มระยะหมดเวลาของการทดสอบ เนื่องจากการระงับและรีสตาร์ทโปรแกรมทำงานของบริการต้องใช้เวลาเพิ่มเติม

การทดสอบเหล่านี้มีประโยชน์เหมือนการดำเนินการผ่านครั้งแรกแบบคร่าวๆ ซึ่งไฮไลต์ตำแหน่งหลายแห่งที่เขียนโค้ดไม่สำเร็จ แต่อาจไม่แสดงให้เห็นถึงวิธีเล็กๆ น้อยๆ ทั้งหมดที่ระงับการทำงานของ Service Worker อาจทำให้สิ่งต่างๆ เสียหาย

ภายในเราเรียกการทดสอบประเภทนี้ว่า "การทดสอบ Fuzz" แต่เดิมนั้น การทดสอบ Fuzz คือการนำอินพุตที่ไม่ถูกต้องมาใส่ในโปรแกรม แล้วตรวจสอบว่าโปรแกรมตอบสนองตามสมควร หรืออย่างน้อยก็ไม่ได้เกิดข้อขัดข้อง ในกรณีของเรา "ข้อมูลที่ไม่ถูกต้อง" คือโปรแกรมทำงานของบริการถูกระงับได้ทุกเมื่อ และ "ลักษณะการทำงานที่สมเหตุสมผล" ที่เราคาดหวังคือ ฟังก์ชันการกรองโฆษณาของเราจะต้องทำงานต่อไปตามปกติ ข้อมูลนี้ไม่ใช่อินพุตที่ไม่ถูกต้องจริงๆ เพราะเป็นลักษณะการทำงานปกติในไฟล์ Manifest V3 แต่วิธีนี้จะไม่ถูกต้องในไฟล์ Manifest V2 จึงดูเป็นคำศัพท์ที่สมเหตุสมผล

สรุป

โปรแกรมทำงานของบริการคือหนึ่งในการเปลี่ยนแปลงที่ใหญ่ที่สุดในไฟล์ Manifest V3 (นอกเหนือจากกฎ declarativeNetRequest) การย้ายข้อมูลไปยังไฟล์ Manifest V3 อาจทำให้คุณต้องเปลี่ยนแปลงโค้ดหลายอย่างในส่วนขยายเบราว์เซอร์และแนวทางใหม่ๆ ในการทดสอบ นอกจากนี้ ยังกำหนดให้นักพัฒนาซอฟต์แวร์ส่วนขยายที่มีสถานะถาวรต้องเตรียมส่วนขยายให้พร้อมรับมือกับการระงับ Service Worker ที่ไม่คาดคิดอย่างดีด้วย

น่าเสียดายที่ไม่มี API สำหรับจัดการการระงับในรูปแบบที่ง่ายดายและตรงตามกรณีการใช้งานของเรา เนื่องจากเราต้องการทดสอบประสิทธิภาพของโค้ดเบสของส่วนขยายกับกลไกการระงับในระยะเริ่มต้น เราจึงต้องแก้ปัญหาดังกล่าว นักพัฒนาส่วนขยายรายอื่นๆ ที่พบความท้าทายคล้ายๆ กันสามารถใช้วิธีแก้ปัญหานี้ได้ แม้จะต้องใช้เวลามากในขั้นตอนการพัฒนาและบำรุงรักษา ก็ถือว่าคุ้มค่ามาก เนื่องจากเราสามารถดูแลให้ส่วนขยายของเราสามารถทำงานในสภาพแวดล้อมที่พนักงานบริการถูกระงับเป็นประจำได้

แม้ว่าจะมีการสนับสนุนพื้นฐานสำหรับการทดสอบการระงับการทำงานของ Service Worker อยู่แล้ว แต่การสนับสนุนแพลตฟอร์มสำหรับทดสอบ Service Worker ที่ดีขึ้นจากภายในส่วนขยายเป็นสิ่งที่เราอยากเห็นในอนาคตจริงๆ เพราะจะช่วยลดเวลาดำเนินการทดสอบและการบำรุงรักษาลงได้มาก